# -*- coding: utf-8 -*-
"""
Created on Fri Feb  1 19:34:35 2019
python3.6.3
Anaconda->spyder
opencv3.4.5
代码参考《OpenCV3计算机视觉 Python语言实现》（第二版）
这个方法绘制边框只有当对比非常明显时才起作用
比如黑白分明
@author: Administrator
"""

import cv2
import numpy as np

#pyrDown()和pryUp()为金字塔函数
#pyrDown()先对图像进行高斯平滑，然后再进行降采样，减小了图像的尺寸
img = cv2.pyrDown(cv2.imread('pycv.png',cv2.IMREAD_UNCHANGED))
img2 = img.copy()

"""
cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)中
使用了cv2.COLOR_BGR2GRAY,
BGR2GRAY 是指将彩色图转化为灰度图
所以img2必须是彩图
"""
ret,thresh = cv2.threshold(cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY),127,255,cv2.THRESH_BINARY)
image,contours,hier = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
contours_np = np.array(contours)
#print(contours_np)
print('contours_np.shape: ', contours_np.shape)  #不定维度查看的结果是不准确的，需要打印看看内容
print('contours_np[0].shape: ', contours_np[0].shape) 

for c in contours:
    #find bounding box coordinates
    '''x，y是矩阵左上点的坐标，w，h是矩阵的宽和高'''
#    c_np = np.array(c)
#    print('c:',c_np.shape)  #每个物体C含有的点的数量都不一样
    x,y,w,h = cv2.boundingRect(c) #即使只有一个点的目标也可以，它的高和宽为1像素
#    print('h:',h)
    """
    第一个参数：img是原图
    第二个参数：（x，y）是矩阵的左上点坐标
    第三个参数：（x+w，y+h）是矩阵的右下点坐标
    第四个参数：（0,255,0）是画线对应的BGR颜色
    第五个参数：3是所画的线的宽度
    """
    cv2.rectangle(img2,(x,y),(x+w,y+h),(0,255,0),3) #较准确 #画绿色矩形
    
    #find minimun area
    '''得到最小外接矩形的'''
    rect = cv2.minAreaRect(c)    
    #calculate coordinates of the minimun area rectangle
    '''获取最小外接矩形的4个顶点'''
    #box里面的坐标全是浮点数
    box = cv2.boxPoints(rect)  
    #normalize coordinates to integers
    '''转化为整形'''
    box = np.int0(box)
    #draw contours
    cv2.drawContours(img2,[box],0,(0,0,255),3) #可以画在任意方向 #画红色矩形
    
    #calculate center and radius of minimum enclosing circle
    '''找出contours的所包围的中心，并计算出半径'''
    #计算出来的也是浮点数
    #可以选择把半径小于2像素的点去掉
    (x,y),radius = cv2.minEnclosingCircle(c) #即使目标只有一个点也会被计算
#    print('(x,y)', x, ' ', y, 'radius', radius)
    #cast to integers
    center = (int(x),int(y))
    radius = int(radius)
    #draw the circle
    img2 = cv2.circle(img,center,radius,(255,255,0),2) #较准确  #画圆形

'''contours是找到的边界的所有点，直接画出来就会类似过拟合''' 
#-1表示绘制所有轮廓，不为-1则只绘制指定的轮廓   
cv2.drawContours(img2,contours,-1,(255,0,0),2)
cv2.imshow('contours',img2)
cv2.waitKey()
cv2.destroyAllWindows()

